import random
import sys


class View:
    @staticmethod
    def welcome():
        print("\n******************************************")
        print("***                                    ***")
        print("***     欢迎登录银行管理系统           ***")
        print("***                                    ***")
        print("******************************************\n")

    @staticmethod
    def menu():
        print("\n******************************************")
        print("***  1.开户(1)      2.查询(2)          ***")
        print("***  3.取款(3)      4.存款(4)          ***")
        print("***  5.转账(5)      6.锁定(6)          ***")
        print("***  7.解锁(7)      退出(Q)            ***")
        print("******************************************\n")

    @staticmethod
    def input_admin():
        account = input("请输入管理员账户：").strip()
        pwd = input("请输入密码：").strip()
        return account, pwd

    @staticmethod
    def pause():
        input("按回车键继续...")

class Admin:
    def __init__(self, username, password):
        self.set_username(username)
        self.set_password(password)

    def set_username(self, username):
        if not isinstance(username, str) or len(username) < 3:
            raise ValueError("管理员账号输入错误")
        self._username = username

    def set_password(self, password):
        if not isinstance(password, str) or len(password) < 5:
            raise ValueError("密码输入错误")
        self._password = password

    def get_username(self):
        return self._username

    def get_password(self):
        return self._password

    username = property(get_username, set_username)
    password = property(get_password, set_password)

    # ---------- 业务行为 ----------
    def admin_login(self) -> bool:
        """登录验证：输对就返回 True，否则 False。"""
        acc, pwd = input("请输入管理员账号："), input("请输入管理员密码：")
        # 真正和实例里存的数据比较
        if acc == self.username and pwd == self.password:
            print("操作成功，请稍后")
            return True
        elif acc != self.username :
            print("管理员账户输入错误，程序即将退出...")
            return False
        elif pwd != self.password:
            print("密码输入错误，程序即将退出...")
            return False
    def admin_logout(self) -> None:
        """退出验证：输对就退出程序，否则返回菜单。"""
        acc, pwd = input("请输入管理员账号："), input("请输入管理员密码：")
        if acc == self.username and pwd == self.password:
            print("退出系统，再见！")
            sys.exit(0)
        else:
            print("管理员账户或密码输入错误，返回功能菜单")

class Card:
    def __init__(self, name, id_no, phone, balance, password):
        self.name = name
        self.id_no = id_no
        self.phone = phone
        self.balance = float(balance)
        self.password = password
        self.locked = False
        self.err_count = 0          # 连续输错密码次数

    def check_pwd(self, pwd):
        """返回 True/False，并自动统计连续错误次数"""
        if self.password == pwd:
            self.err_count = 0
            return True
        self.err_count += 1
        if self.err_count >= 3:
            self.locked = True
        return False

    def lock(self):
        self.locked = True

    def unlock(self):
        self.locked = False
        self.err_count = 0

class Bank:
    def __init__(self):
        self.cards = {}          # card_no -> Card

    def generate_card_no(self):
        """生成 6 位不重复的卡号"""
        while True:
            no = str(random.randint(100000, 999999))
            if no not in self.cards:
                return no

    def create_card(self, name, id_no, phone, balance, password):
        card_no = self.generate_card_no()
        self.cards[card_no] = Card(name, id_no, phone, balance, password)
        return card_no

    def get_card(self, card_no):
        return self.cards.get(card_no)

    def transfer(self, from_no, to_no, amount):
        """转账业务，返回 (bool, msg)"""
        if from_no == to_no:
            return False, "转出与转入卡号不能相同"
        from_card = self.get_card(from_no)
        to_card = self.get_card(to_no)
        if not from_card or not to_card:
            return False, "卡号不存在"
        if from_card.locked or to_card.locked:
            return False, "卡号已被锁定"
        if amount <= 0:
            return False, "转账金额必须大于 0"
        if from_card.balance < amount:
            return False, "余额不足"
        from_card.balance -= amount
        to_card.balance += amount
        return True, "转账成功"

class Controller:
    # --- 业务 ---
    def __init__(self):
        self.bank = Bank()
        self.admin = Admin("admin", "12345")

    def create_account(self):
        print("=== 开户 ===")
        name = input("姓名：").strip()
        id_no = input("身份证号：").strip()
        phone = input("手机号：").strip()
        balance = float(input("预存金额："))
        pwd = input("密码：").strip()
        card_no = self.bank.create_card(name, id_no, phone, balance, pwd)
        print(f"开户成功，卡号：{card_no}")

    def query(self):
        print("=== 查询 ===")
        card_no = input("卡号：").strip()
        card = self.bank.get_card(card_no)
        if not card:
            print("卡号不存在")
            return
        pwd = input("密码：").strip()
        if not card.check_pwd(pwd):
            print(f"密码错误，已错误 {card.err_count} 次")
            if card.locked:
                print("卡号已被锁定")
            return
        if card.locked:
            print("卡号已被锁定，无法查询")
            return
        print(f"余额：{card.balance:.2f} 元")

    def withdraw(self):
        print("=== 取款 ===")
        card_no = input("卡号：").strip()
        card = self.bank.get_card(card_no)
        if not card:
            print("卡号不存在")
            return
        pwd = input("密码：").strip()
        if not card.check_pwd(pwd):
            print(f"密码错误，已错误 {card.err_count} 次")
            if card.locked:
                print("卡号已被锁定")
            return
        if card.locked:
            print("卡号已被锁定，无法取款")
            return
        amount = float(input("取款金额："))
        if amount <= 0:
            print("金额必须大于 0")
            return
        if amount > card.balance:
            print("余额不足")
            return
        card.balance -= amount
        print(f"取款成功，余额：{card.balance:.2f} 元")

    def deposit(self):
        print("=== 存款 ===")
        card_no = input("卡号：").strip()
        card = self.bank.get_card(card_no)
        if not card:
            print("卡号不存在")
            return
        pwd = input("密码：").strip()
        if not card.check_pwd(pwd):
            print(f"密码错误，已错误 {card.err_count} 次")
            if card.locked:
                print("卡号已被锁定")
            return
        if card.locked:
            print("卡号已被锁定，无法存款")
            return
        amount = float(input("存款金额："))
        if amount <= 0:
            print("金额必须大于 0")
            return
        card.balance += amount
        print(f"存款成功，余额：{card.balance:.2f} 元")

    def transfer(self):
        print("=== 转账 ===")
        from_no = input("转出卡号：").strip()
        to_no = input("转入卡号：").strip()
        amount = float(input("转账金额："))
        ok, msg = self.bank.transfer(from_no, to_no, amount)
        print(msg)
        if ok:
            print(f"转出卡余额：{self.bank.get_card(from_no).balance:.2f} 元")

    def lock_card(self):
        print("=== 锁定 ===")
        card_no = input("卡号：").strip()
        card = self.bank.get_card(card_no)
        if not card:
            print("卡号不存在")
            return
        pwd = input("密码：").strip()
        if not card.check_pwd(pwd):
            print("密码错误")
            return
        card.lock()
        print("锁定成功")

    def unlock_card(self):
        print("=== 解锁 ===")
        card_no = input("卡号：").strip()
        card = self.bank.get_card(card_no)
        if not card:
            print("卡号不存在")
            return
        pwd = input("密码：").strip()
        if not card.check_pwd(pwd):
            print("密码错误")
            return
        card.unlock()
        print("解锁成功")
    def run(self):
            View.welcome()
            if not self.admin.admin_login():
                return
            while True:
                View.menu()
                choice = input("请选择功能：").strip().upper()
                if choice == "1":
                    self.create_account()
                elif choice == "2":
                    self.query()
                elif choice == "3":
                    self.withdraw()
                elif choice == "4":
                    self.deposit()
                elif choice == "5":
                    self.transfer()
                elif choice == "6":
                    self.lock_card()
                elif choice == "7":
                    self.unlock_card()
                elif choice == "Q":
                    self.admin.admin_logout()
                else:
                    print("输入有误，请重新选择")
                View.pause()
if __name__ == "__main__":
    Controller().run()
